package lk.mrt.cse.wihidum.processor;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.SOAPFactory;
import org.apache.log4j.Logger;

import javax.xml.namespace.QName;

import lk.mrt.cse.wihidum.util.WSEventingConstants;
import lk.mrt.cse.wihidum.util.SelfReader;
import lk.mrt.cse.wihidum.util.WihidumConstants;
import lk.mrt.cse.wihidum.communicator.XMLReader;
import lk.mrt.cse.wihidum.communicator.Router;
import lk.mrt.cse.wihidum.communicator.ClusterRouter;
import lk.mrt.cse.wihidum.communicator.TreeRouter;
import lk.mrt.cse.wihidum.storage.*;

import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 * User: Wihidum
 * Date: Jun 2, 2010
 * Time: 9:22:24 PM
 * To change this template use File | Settings | File Templates.
 */
public class AdminProcessor implements Processor
{
    private static final Logger logger = Logger.getLogger (AdminProcessor.class);

    public SOAPEnvelope processMessage(SOAPEnvelope requestEnvelope, String messageID)
    {
       SOAPFactory factory = OMAbstractFactory.getSOAP11Factory();
       SOAPEnvelope responseEnvelop = factory.getDefaultEnvelope();      

       OMElement topologyElement = requestEnvelope.getBody()
               .getFirstChildWithName(new QName(WSEventingConstants.WIHIDUM_NAMESPACE, "TopologyDetails"))
               .getFirstChildWithName(new QName(WSEventingConstants.WIHIDUM_NAMESPACE, "Topology"));

       OMElement responseElement = factory.createOMElement("Response", null);
       if(this.changeTopology(topologyElement.getText()))
       {
           responseElement.setText("Topology changed to " +topologyElement.getText() + " successfully");
       }
       else
       {
           responseElement.setText("Error in topology changing to " +topologyElement.getText() + " at broker: "+ SelfReader.getMyID() +" successfully");
       }
       responseEnvelop.getBody().addChild(responseElement);
       return responseEnvelop;
    }

    private boolean changeTopology(String topology)
    {
        try
        {
            //Change the topology in the in memory selfMap
            if(topology.equals(SelfReader.setTopology(topology)))
            {
                //Clear the broker subscription map
                BrokerSubscriptionMap.clearBrokerSubscriptionMap();

                //Read the topology configuration file corresponsing to new topology
                Topology.setReadOnce(false);
                Router router;
                if(topology.equals(WihidumConstants.TopologyNames.clusterTopology))
                {
                    router = new ClusterRouter();
                }
                else
                {
                    router = new TreeRouter();
                }

                String action = WihidumConstants.Actions.Subscribe;
                String filter, logUUID;
                Map<SubscriberIdentifier,Subscriber> subMap = SubscriptionMap.getAllSubscribers();
                if(!subMap.isEmpty())
                {
                     for(Map.Entry<SubscriberIdentifier,Subscriber> entry:subMap.entrySet())
                     {
                            filter = entry.getKey().getFilterTopic();
                            logUUID =  entry.getValue().getUuid();
                            router.reRouteAllSubscriptions(filter, action, logUUID);
                     }
                }
            }
            return true;
        }
        catch (Exception ex)
        {
            logger.error(ex.getMessage());
            return false;
        }
    }

    public OMElement processPropogatingMessage(SOAPEnvelope requestEnvelop, String messageID)
    {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }
}
